﻿/*   
    Copyright (C) 2009 Galaktika Corporation ZAO

    This file is a part of Galaktika.BusinessMonitor
 
    Galaktika.BusinessMonitor is a free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
      
    You should have received a copy of the GNU General Public License
    along with Galaktika.BusinessMonitor.  If not, see <http://www.gnu.org/licenses/>.
  
    If GPL v.3 is not suitable for your products or company,
    Galaktika Corp provides Galaktika.BusinessMonitor under a flexible commercial license
    designed to meet your specific usage and distribution requirements.
    If you have already obtained a commercial license from Galaktika Corp,
    you can use this file under those license terms.
*/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Serialization;
using System.Runtime.Serialization;
using Galaktika.BI.Silverlight;
using System.Security.Cryptography;
using System.Text;

namespace Galaktika.BI.Silverlight.Services
{
    [XmlRoot(Namespace = Common.Namespace)]
    [DataContract(Namespace = Common.Namespace)]
    public class InvokeSchema
    {
        public InvokeSchema()
        {
            m_Args = new List<InvokeArg>();
        }

        public InvokeSchema(string commandId)
        {
            if (string.IsNullOrEmpty(commandId))
            {
                throw new ArgumentNullException("commandId");
            }

            this.CommandId = commandId;
            m_Args = new List<InvokeArg>();
        }

        public InvokeSchema(string commandId, IDictionary<string, string> args)
        {
            if (string.IsNullOrEmpty(commandId))
            {
                throw new ArgumentNullException("commandId");
            }
            if (args == null)
            {
                throw new ArgumentNullException("args");
            }

            this.CommandId = commandId;
            m_Args = new List<InvokeArg>();
            foreach (KeyValuePair<string, string> kv in args)
            {
                this.Args.Add(new InvokeArg(kv.Key, kv.Value));
            }
        }

        public InvokeSchema(string commandId, IEnumerable<InvokeArg> args)
        {
            if (string.IsNullOrEmpty(commandId))
            {
                throw new ArgumentNullException("commandId");
            }
            if (args == null)
            {
                throw new ArgumentNullException("args");
            }

            this.CommandId = commandId;
            m_Args = new List<InvokeArg>(args);
        }

        [XmlElement]
        [DataMember]
        public string CommandId { get; set; }

        private List<InvokeArg> m_Args;
        [XmlArray]
        [XmlArrayItem(typeof(InvokeArg))]
        [DataMember]
        public List<InvokeArg> Args 
        {
            get
            {
                return m_Args;
            }
        }

        private Dictionary<string, string> m_Cache;
        private void EnsureCache()
        {
            if (m_Cache == null)
            {
                m_Cache = new Dictionary<string, string>();
                foreach (InvokeArg arg in this.Args)
                {
                    m_Cache.Add(arg.Name, arg.Value);
                }
            }
        }

        [XmlIgnore]
        [IgnoreDataMember]
        public string this[string name]
        {
            get
            {
                this.EnsureCache();
                string res;
                m_Cache.TryGetValue(name, out res);

                return res;
            }
            set
            {
                foreach (InvokeArg arg in m_Args)
                {
                    if (name == arg.Name)
                    {
                        arg.Value = value;
                        m_Cache = null;
                        break;
                    }
                }
            }
        }

        [XmlIgnore]
        [IgnoreDataMember]
        public IDictionary<string, string> AsDictionary
        {
            get
            {
                this.EnsureCache();

                return m_Cache;
            }
        }

        public string GetSHA1Hash()
        {
            string hashInput = CommandId;
            foreach(InvokeArg arg in Args)
                hashInput += String.Format("[{0}:{1}]", arg.Name, arg.Value);

            SHA1Managed sha1 = new SHA1Managed();
            string hash = BitConverter.ToString(sha1.ComputeHash(Encoding.Unicode.GetBytes(hashInput))).Replace("-", "");
            return hash;
        }
    }

    [XmlRoot(Namespace = Common.Namespace)]
    [DataContract(Namespace = Common.Namespace)]
    public class InvokeArg
    {
        public InvokeArg()
        {
        }

        public InvokeArg(string name, string value)
        {
            this.Name = name;
            this.Value = value;
        }

        [XmlElement]
        [DataMember]
        public string Name { get; set; }

        [XmlElement]
        [DataMember]
        public string Value { get; set; }
    }

    public class KnownInvokeArgs
    {
        public readonly static string ContextId = "ContextId";
        public readonly static string DataSourceId = "DataSourceId";
        public readonly static string ConnectionId = "ConnectionId";
        public readonly static string QueryId = "QueryId";
        public readonly static string NameValueCollection = "NameValueCollection";
        public readonly static string Path = "Path";
        public readonly static string MemberAction = "MemberAction";
        public readonly static string UpdateCube = "UpdateCube";
        public readonly static string GetPivotDataCommand = "GetPivotData";
        public readonly static string ExecuteQueryCommand = "ExecuteQuery";
        public readonly static string PivotGridServiceCommand = "ServiceCommand";
        public readonly static string PivotGridToolBarInfo = "PivotGridToolBarInfo";
        public readonly static string MemberChoiceQueryInfo = "MemberChoiceQueryInfo";
        public readonly static string DateChoiceQueryInfo = "DateChoiceQueryInfo";
        public readonly static string MetadataQueryInfo = "MetadataQueryInfo";
        public readonly static string ConnectionName = "ConnectionName";
        public readonly static string FunctionName = "FunctionName";
        public readonly static string ArgumentName = "Argument";
        public readonly static string ResetContext = "ResetContext";
        public readonly static string ChangeDataSource = "ChangeDataSource";
        public readonly static string ConnectionString = "ConnectionString";
        public readonly static string Query = "Query";
        public readonly static string ConnectionType = "ConnectionType";
        public readonly static string SessionId = "SessionId";
        public readonly static string NonQuery = "NonQuery";
        public readonly static string CubeName = "CubeName";
        public readonly static string DimensionUniqueName = "DimensionUniqueName";
        public readonly static string HierarchyUniqueName = "HierarchyUniqueName";
        public readonly static string LevelUniqueName = "LevelUniqueName";
        public readonly static string MeasureUniqueName = "MeasureUniqueName";
        public readonly static string KpiUniqueName = "KpiUniqueName";
        public readonly static string UpdateScript = "UpdateScript";
        public readonly static string StorageAction = "StorageAction";
    }

    public enum ConnectionType
    {
        OleDb,
        Odbc,
        SqlServer,
        Olap
    }
}
